//
//  SleepQualityCalculator.swift
//  MoYoung
//
//  Created by sylar on 2017/11/11.
//  Copyright © 2017年 sylar. All rights reserved.
//

import Foundation

import MYModule

public class SleepQualityCalculator {
    
    public let max_sleep_quality_value = 100
    public let quality_factor = 3
    
    public let excellent_quality_fraction = 0
    public let good_quality_fraction = 1
    public let medium_quality_fraction = 2
    public let poor_quality_fraction = 3
    
    public let excellent_regular_sleep = 7
    public let good_regular_sleep = 5
    public let medium_regular_sleep = 3
    
    public let excellent_sleep_time = 7
    public let good_sleep_time = 6
    public let medium_sleep_time = 5
    
    public let excellent_restful_percent = 20
    public let good_restful_percent = 15
    public let medium_restful_percent = 10
    
    public let excellent_awake_count = 1
    public let good_awake_count = 2
    public let medium_awake_count = 3
    public let poor_awake_count = 5
    
    public let excellent_awake_time = 5
    public let good_awake_time = 10
    public let medium_awake_time = 15
    
    public let excellent_start_sleep_hour = 23
    public let good_start_sleep_hour = 24
    public let medium_start_sleep_hour = 25
    
    public var quality = 0
    /**
     * 计算睡眠质量
     *
     * 1.睡眠规律性 最近7天
     * 2.睡眠时长   当天
     * 3.深睡眠比例
     * 4.醒来次数
     * 5.醒来时间
     * 6.入睡时间
     *
     * @param data
     * @return
     */
    public init(last7Days:[SleepModel]) {
        if let today = last7Days.last {
            if (today.total > 0){
                
                var badQuality = 0
                
                badQuality += self.getRegularSleepQuality(last7Days)
                log.debug(badQuality)
                let totalTime = today.total
                badQuality += self.getSleepTimeQuality(totalTime/60)
                log.debug(badQuality)
                let deepTime = today.deep
                let restfulPercent = Int(Float(deepTime) / Float(totalTime) * 100)
                badQuality += self.getRestfulPercentQuality(restfulPercent)
                log.debug(badQuality)
                let awakes = self.getAwakeCountAndStart(today)
                badQuality += self.getAwakeCountQuality(awakes[0])
                log.debug(badQuality)
                badQuality += self.getAwakeTimeQuality(awakes[1])
                log.debug(badQuality)
                badQuality += self.getStartSleepTimeQuality(awakes[2])
                log.debug(badQuality)
                self.quality = max_sleep_quality_value - (badQuality * quality_factor)
            }
        }
    }
    
    /**
     * 获取睡眠规律性评分
     *
     * @param dayNumber 天数
     * @return
     */
    private func getRegularSleepQuality(_ last7Days:[SleepModel])->Int {
        
        var dayNumber = 0
        for item in last7Days {
            let total = item.total
            if (total > 0) {
                dayNumber += 1
            }
        }
        
        if (dayNumber >= excellent_regular_sleep){
            return excellent_quality_fraction
        }else if (dayNumber >= good_regular_sleep){
            return good_quality_fraction
        }else if (dayNumber >= medium_regular_sleep){
            return medium_quality_fraction
        }else {
            return poor_quality_fraction
        }
    }
    
    /**
     * 获取睡眠时长评分
     *
     * @param sleepHours 单位：小时
     * @return
     */
    private func getSleepTimeQuality(_ sleepHours:Int)->Int {
        if (sleepHours >= excellent_sleep_time){
            return excellent_quality_fraction
        }else if (sleepHours >= good_sleep_time){
            return good_quality_fraction
        }else if (sleepHours >= medium_sleep_time){
            return medium_quality_fraction
        }else {
            return poor_quality_fraction
        }
    }
    
    /**
     * 获取深睡眠比例评分
     *
     * @param percent 百分比
     * @return
     */
    private func getRestfulPercentQuality(_ percent:Int)->Int {
        if (percent >= excellent_restful_percent){
            return excellent_quality_fraction
        }else if (percent >= good_restful_percent){
            return good_quality_fraction
        }else if (percent >= medium_restful_percent){
            return medium_quality_fraction
        }else {
            return poor_quality_fraction
        }
    }
    
    /**
     * 获取醒来次数评分
     *
     * @param count 次数
     * @return
     */
    private func getAwakeCountQuality(_ count:Int)->Int {
        if (count <= excellent_awake_count){
            return excellent_quality_fraction
        }else if (count <= good_awake_count){
            return good_quality_fraction
        }else if (count <= medium_awake_count){
            return medium_quality_fraction
        }else {
            return poor_quality_fraction
        }
    }
    
    /**
     * 获取醒来时间评分
     *
     * @param time 单位：分钟
     * @return
     */
    private func getAwakeTimeQuality(_ time:Int)->Int{
        if (time <= excellent_awake_time){
            return excellent_quality_fraction
        }else if (time <= good_awake_time){
            return good_quality_fraction
        }else if (time <= medium_awake_time){
            return medium_quality_fraction
        }else {
            return poor_quality_fraction
        }
    }
    
    /**
     * 获取入睡时间评分
     *
     * @param hour 单位：小时
     * @return
     */
    private func getStartSleepTimeQuality(_ hour:Int)->Int {
        var startHour = hour
        if (startHour < 12){
            startHour += 24
        }
        
        if (startHour <= excellent_start_sleep_hour){
            return excellent_quality_fraction
        }else if (startHour <= good_start_sleep_hour){
            return good_quality_fraction
        }else if (startHour <= medium_start_sleep_hour){
            return medium_quality_fraction
        }else {
            return poor_quality_fraction
        }
    }
    
    /**
     * 获取醒来次数, 醒来时长 入睡时间
     *
     * @param todaySleep
     * @return [醒来次数, 醒来时长, 入睡时间]
     */
    private func getAwakeCountAndStart(_ today:SleepModel)->[Int] {
        
        var iAwakeCount:Int = 0
        var iAwakeTotal:Int = 0
        var iStart:Int = 0
        
        let detail = today.detail
        if detail.count == 0 {
            return [0, 0, 0]
        }
        
        for i in 0..<detail.count {
            let value = detail[i]
            let type = value.type
            let total = value.total
            
            if type == 0 {
                iAwakeCount += 1
                iAwakeTotal += total
            }
            if i == 0 {
                let start = value.start
                let starts = start.components(separatedBy: ":")
                iStart = Int(starts[0])!
            }
        }
        
        return [iAwakeCount, iAwakeTotal, iStart]
    }
}

